package smtpserver

import (
	"bufio"
	"context"
	"fmt"
	"net"
	"strings"
	"sync"

	"github.com/nosch/smtpoll/logger"
)

// NetServer 标准库实现的服务器
type NetServer struct {
	options   *ServerOptions
	handler   MessageHandler
	listeners []net.Listener
	wg        sync.WaitGroup
	stopCh    chan struct{} // 用于通知停止接受新连接
}

// NewNetServer 创建新的标准库服务器
func NewNetServer(options *ServerOptions, handler MessageHandler) *NetServer {
	return &NetServer{
		options:   options,
		handler:   handler,
		listeners: make([]net.Listener, 0),
		stopCh:    make(chan struct{}),
	}
}

// Run 运行服务器
func (s *NetServer) Run() error {
	// 为每个端口创建监听器
	for _, port := range s.options.Ports {
		addr := fmt.Sprintf("%s:%d", s.options.Host, port)
		logger.LogInfo(context.Background(), "Creating net listener", "addr", addr)

		listener, err := net.Listen("tcp", addr)
		if err != nil {
			logger.LogError(context.Background(), "Failed to create listener", "addr", addr, "error", err)
			return fmt.Errorf("failed to listen on %s: %v", addr, err)
		}

		// 将监听器添加到切片中
		s.listeners = append(s.listeners, listener)

		logger.LogInfo(context.Background(), "Net SMTP server listening", "addr", addr)

		go func(l net.Listener, a string) {
			for {
				select {
				case <-s.stopCh:
					logger.LogInfo(context.Background(), "Stopping accept new connections", "addr", a)
					return
				default:
					conn, err := l.Accept()
					if err != nil {
						// 忽略关闭连接的错误
						if !strings.Contains(err.Error(), "use of closed network connection") {
							logger.LogError(context.Background(), "Error accepting connection", "addr", a, "error", err)
						}
						return
					}

					logger.LogInfo(context.Background(), "New connection accepted",
						"remote_addr", conn.RemoteAddr().String(),
						"local_addr", conn.LocalAddr().String())

					s.wg.Add(1)
					go s.handleConnection(conn)
				}
			}
		}(listener, addr)
	}

	return nil
}

// handleConnection 处理新的连接
func (s *NetServer) handleConnection(conn net.Conn) {
	defer s.wg.Done()
	defer conn.Close()

	// 创建适配器
	adapter := NewNetConnAdapter(conn)

	// 创建会话
	session := NewSession(adapter, s.handler, NewDefaultAuthSource())

	// 创建带缓冲的读取器
	reader := bufio.NewReader(conn)

	// 处理会话
	if err := session.ProcessConnection(reader); err != nil {
		logger.LogError(session.ctx, "Session processing failed", "error", err)
	}
}

// Stop 停止服务器
func (s *NetServer) Stop() error {
	logger.LogInfo(context.Background(), "Stopping net server")

	// 1. 首先通知停止接受新连接
	close(s.stopCh)

	// 2. 等待所有连接处理完成
	s.wg.Wait()

	// 3. 最后关闭所有监听器
	for _, listener := range s.listeners {
		if err := listener.Close(); err != nil {
			// 忽略关闭连接的错误
			if !strings.Contains(err.Error(), "use of closed network connection") {
				logger.LogError(context.Background(), "Error closing listener", "error", err)
			}
		}
	}

	logger.LogInfo(context.Background(), "Net server stopped")
	return nil
}

// GetOptions 返回服务器配置选项
func (s *NetServer) GetOptions() *ServerOptions {
	return s.options
}
